package net.jumpengine.manager;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import net.jumpengine.Manager;
import net.jumpengine.event.KeyMiddle;
import net.jumpengine.event.MouseMiddle;
import net.jumpengine.inter.IInitReady;
import net.jumpengine.inter.IInputEvent;
import net.jumpengine.inter.IMouseEvent;
import net.jumpengine.inter.IStateEvent;

/**
 * 游戏引擎的事件管理类
 * <br /><br />
 * <b>作者:&nbsp;</b>张天文 <br />
 * <b>日期:&nbsp;</b>2020年2月26日 下午4:18:52<br />
 * @date
 */
public class EventManager  {
	private MouseMiddle mouse=new MouseMiddle();
	private KeyMiddle input=new KeyMiddle();
	private Map<Enum<?>,IStateEvent> stateMap=new HashMap<>();
	private List<IInitReady> readyList=new ArrayList<IInitReady>();
	
	/**
	  * 初始化事件管理器, 对窗体添加监听
	 * @param group
	 * @param scene
	 */
	public void init(Group group,Scene scene) {
		Manager.getLog().debug("EventManager[init]");
		
		group.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent event) {
				mouse.click((int)event.getSceneX(),(int)event.getSceneY(),event.getButton());		
			}
		});
		group.addEventHandler(MouseEvent.MOUSE_MOVED, new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent event) {
				mouse.move((int)event.getSceneX(),(int)event.getSceneY(),event.getButton());			
			}
		});
		group.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent event) {
				mouse.pressed((int)event.getSceneX(),(int)event.getSceneY(),event.getButton());				
			}
		});
		group.addEventHandler(MouseEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent event) {
				mouse.released((int)event.getSceneX(),(int)event.getSceneY(),event.getButton());					
			}
		});
		
		scene.addEventHandler(KeyEvent.KEY_PRESSED,new EventHandler<KeyEvent>() {
			@Override
			public void handle(KeyEvent event) {
				input.pressed(event.getCharacter(),event.getCode(),event.getText());
			}
		});
		scene.addEventHandler(KeyEvent.KEY_RELEASED,new EventHandler<KeyEvent>() {
			@Override
			public void handle(KeyEvent event) {
				input.released(event.getCharacter(),event.getCode(),event.getText());
			}
		});
		scene.addEventHandler(KeyEvent.KEY_TYPED,new EventHandler<KeyEvent>() {
			@Override
			public void handle(KeyEvent event) {
				input.typed(event.getCharacter(),event.getCode(),event.getText());
			}
		});
	}
	
	/**
         * 添加鼠标事件处理类
	 * @param t 游戏状态
	 * @param obj 鼠标事件处理类
	 */
	public void addMouseEvent(Enum<?> e,IMouseEvent obj) {
		mouse.put(e, obj);
		
		if(obj instanceof IInitReady) {
			IInitReady read=(IInitReady) obj;
			if(!readyList.contains(read))readyList.add(read);
		}
	}
	
	/**
	 * 添加按键事件管理类
	 * @param t 游戏状态
	 * @param obj 按键事件管理类
	 */
	public void addInputEvent(Enum<?> e,IInputEvent obj) {
		input.put(e,obj);
		
		if(obj instanceof IInitReady) {
			IInitReady read=(IInitReady) obj;
			if(!readyList.contains(read))readyList.add(read);
		}
	}
	
	/**
	  * 添加游戏状态管理类
	 * @param t 游戏状态
	 * @param obj 游戏状态管理类
	 */
	public void addStateEvent(Enum<?> e,IStateEvent obj) {
		stateMap.put(e, obj);
		
		if(obj instanceof IInitReady) {
			IInitReady read=(IInitReady) obj;
			if(!readyList.contains(read))readyList.add(read);
		}
	}
	
	public void initReady() {
		for(IInitReady ready:readyList) {
			ready.init();
		}
	}
	
	public IStateEvent currentStateEvent() {
		return stateMap.get(Manager.getState());
	}
	
	public IInputEvent getInputEvent(Enum<?> e){
		return input.get(e);
	}
	
	public IMouseEvent getMouseEvent(Enum<?> e){
		return mouse.get(e);
	}
	
	public IStateEvent getStateEvent(Enum<?> e){
		return stateMap.get(e);
	}
	
	public boolean hasEventState(Enum<?> e) {
		return stateMap.containsKey(e);
	}
}
